package rpc.frame.server.registry.zk;

import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import rpc.frame.core.annotation.RpcServer;
import rpc.frame.core.spring.SpringBeanFactory;
import rpc.frame.core.util.IpUtil;
import rpc.frame.server.config.RpcServerConfiguration;
import rpc.frame.server.registry.RpcRegistry;

import javax.annotation.Resource;
import java.util.Map;

@Component
@Slf4j
@DependsOn("springBeanFactory")
public class zkRegistry implements RpcRegistry {

    @Resource
    private ServerZk serverZk;

    @Resource
    private RpcServerConfiguration rpcServerConfiguration;
    /**
     * 服务注册流程
     * 1.获取zk链接参数 如：连接地址、端口号、超时时常
     *     这些参数 由引入的项目提供所以需要 获取demo中的配置项目
     * 2、获取注册的规则 如：接口名/方法名/ip:端口
     *      根节点从用户配置读取。接口名读取配置了需要注册的接口
     * 3、决策使用的客户端 zkClient
     */
    @Override
    public void serviceRegistry() {
        //1、在需要注册的接口上 添加注解
        Map<String, Object> beanList = SpringBeanFactory.getBeanListByAnnotationClass(RpcServer.class);
        if(beanList!=null){
            //创建根节点
            serverZk.createRootNode();
            //获取当前机器ip 后续客户端直接使用ip进行通讯
            String ip= IpUtil.getRealIp();
            for(Object bean:beanList.values()){
                //根据类的类型获取到类
                RpcServer annotation = bean.getClass().getAnnotation(RpcServer.class);
                Class<?> interfaceClass = annotation.interfaceClass();
                //获取到类的名称
                String interfaceName = interfaceClass.getName();
                // 创建代表接口的持久子节点
                serverZk.createPersistentNode(interfaceName);
                // 当前服务作为该接口的提供者,创建代表当前提供者的临时字节点[在接口下面]
                String providerNode=ip+":"+rpcServerConfiguration.getRpcPort();
                serverZk.createNode(interfaceName+"/"+providerNode);
                log.info("服务注册成功 {} / {}服务已启动",interfaceName,providerNode);

            }
        }

    }
}
